---
type: integration
title: '@astrojs/sitemap'
description: Astro 프로젝트에서 @astrojs/sitemap 통합을 사용하는 방법을 알아보세요.
githubIntegrationURL: 'https://github.com/withastro/astro/tree/main/packages/integrations/sitemap/'
category: other
i18nReady: true
---

import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';

이 **[Astro 통합][astro-integration]** 은 Astro 프로젝트를 빌드할 때 페이지를 기반으로 사이트맵을 생성합니다.

## 왜 Astro Sitemap인가?

사이트맵은 사이트에 있는 모든 페이지, 동영상, 파일의 개요를 설명하는 XML 파일입니다. Google과 같은 검색 엔진은 이 파일을 읽어 사이트를 보다 효율적으로 크롤링합니다. 자세히 알아보려면 [사이트맵에 대한 Google의 조언](https://developers.google.com/search/docs/advanced/sitemaps/overview)을 참조하세요.

대규모 다중 페이지 사이트에는 사이트맵 파일이 권장됩니다. 사이트맵을 사용하지 않는 경우에도 대부분의 검색 엔진은 사이트의 페이지를 나열할 수 있지만 사이트맵은 사이트를 최대한 검색 엔진 친화적으로 만들 수 있는 좋은 방법입니다.

Astro Sitemap을 사용하면 이 XML 파일을 직접 생성하는 것에 대해 걱정할 필요가 없습니다. Astro Sitemap 통합은 정적으로 생성된 경로를 크롤링하여 사이트맵 파일을 생성합니다. 여기에는 `getStaticPaths()`에 의해 생성된 `[...slug]` 또는 `src/pages/[lang]/[version]/info.astro`와 같은 [동적 경로](/ko/guides/routing/#동적-경로)가 포함됩니다.

이 통합은 [SSR 모드](/ko/basics/rendering-modes/#요청-시-렌더링)에서 동적 경로에 대한 사이트맵 항목을 생성할 수 없습니다.

## 설치

Astro에는 공식 통합 설정을 자동화하는 `astro add` 명령이 포함되어 있습니다. 원하는 경우 대신 [통합을 수동으로 설치](#수동-설치)할 수 있습니다.

새 터미널 창에서 다음 명령 중 하나를 실행합니다.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npx astro add sitemap
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro add sitemap
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro add sitemap
  ```
  </Fragment>
</PackageManagerTabs>

문제가 발생하면 [GitHub에서 언제든지 보고](https://github.com/withastro/astro/issues)하고 아래 수동 설치 단계를 시도해 보세요.

### 수동 설치

먼저 패키지 관리자를 사용하여 `@astrojs/sitemap` 패키지를 설치하세요.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm install @astrojs/sitemap
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm add @astrojs/sitemap
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn add @astrojs/sitemap
  ```
  </Fragment>
</PackageManagerTabs>

그런 다음 `integrations` 속성을 사용하여 `astro.config.*` 파일에 통합을 적용합니다.

```js ins={2} ins="sitemap()"
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  // ...
  integrations: [sitemap()],
});
```

## 사용하기

`@astrojs/sitemap`을 생성하려면 배포/사이트 URL이 필요합니다. `site` 속성을 사용하여 `astro.config.*` 파일 아래에 사이트 URL을 추가하세요. 이는 `http:` 또는 `https:`로 시작해야 합니다.

```js title="astro.config.mjs" "'https://stargazers.club'"
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  // ...
  site: 'https://stargazers.club',
  integrations: [sitemap()],
});
```

다른 구성 옵션과 달리 `site`는 `sitemap()` 호출 내부가 아닌 루트 `defineConfig` 객체에 설정됩니다.

이제 `astro build` 명령을 통해 [프로덕션용 사이트를 빌드](/ko/reference/cli-reference/#astro-build)하세요. `dist/` 폴더 (또는 설정된 경우 사용자 정의 [출력 디렉터리](/ko/reference/configuration-reference/#outdir))에서 `sitemap-index.xml`과 `sitemap-0.xml`을 모두 찾을 수 있습니다.

:::caution
`site` 추가를 잊어버린 경우 빌드할 때 경고가 표시되고 `sitemap-index.xml` 파일이 생성되지 않습니다.
:::

사이트맵이 빌드되었는지 확인한 후 이를 사이트의 `<head>` 및 크롤러가 선택할 수 있는 `robots.txt` 파일에 추가할 수 있습니다.

```html title="src/layouts/Layout.astro" ins={2}
<head>
  <link rel="sitemap" href="/sitemap-index.xml" />
</head>
```

```txt ins={5}
# public/robots.txt
User-agent: *
Allow: /

Sitemap: https://<YOUR SITE>/sitemap-index.xml
```

`robots.txt`를 동적으로 생성하려면 다음 코드를 사용하여 `robots.txt.ts`라는 파일을 추가하세요.

```ts title="src/pages/robots.txt.ts"
import type { APIRoute } from 'astro';

const robotsTxt = `
User-agent: *
Allow: /
Sitemap: ${new URL('sitemap-index.xml', import.meta.env.SITE).href}
`.trim();

export const GET: APIRoute = () => {
  return new Response(robotsTxt, {
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
    },
  });
};

```

### 두 페이지로 구성된 웹사이트용으로 생성된 파일의 예시

```xml title="sitemap-index.xml"
<?xml version="1.0" encoding="UTF-8"?>
  <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://stargazers.club/sitemap-0.xml</loc>
  </sitemap>
</sitemapindex>
```

```xml title="sitemap-0.xml"
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
  <url>
    <loc>https://stargazers.club/</loc>
  </url>
  <url>
    <loc>https://stargazers.club/second-page/</loc>
  </url>
</urlset>
```

## 구성

이 통합을 구성하려면 `astro.config.mjs` 파일의 `sitemap()` 함수 호출에 객체를 전달하세요.

```js title="astro.config.mjs" {6-8}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  integrations: [
    sitemap({
      // 구성 옵션
    }),
  ],
});
```

### filter

모든 페이지는 기본적으로 사이트맵에 포함됩니다. 사용자 정의 `filter` 함수를 추가하면 포함된 페이지를 URL별로 필터링할 수 있습니다.

```js title="astro.config.mjs" ins={8}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      filter: (page) => page !== 'https://stargazers.club/secret-vip-lounge/',
    }),
  ],
});
```

이 함수는 사이트의 모든 페이지에 대해 호출됩니다. `page` 함수의 매개변수는 `site` 도메인을 포함하여 현재 고려 중인 페이지의 전체 URL입니다. 사이트맵에 페이지를 포함하려면 `true`를 반환하고, 제외하려면 `false`를 반환합니다.

여러 페이지를 필터링하려면 대상 URL이 포함된 인수를 추가하세요.

```js title="astro.config.mjs" {8-12}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      filter: (page) =>
        page !== 'https://stargazers.club/secret-vip-lounge-1/' &&
        page !== 'https://stargazers.club/secret-vip-lounge-2/' &&
        page !== 'https://stargazers.club/secret-vip-lounge-3/' &&
        page !== 'https://stargazers.club/secret-vip-lounge-4/',
    }),
  ],
});
```

### customPages

어떤 경우에는 페이지가 배포된 사이트의 일부이지만 Astro 프로젝트의 일부가 아닐 수도 있습니다. Astro에서 생성하지 *않은* 페이지를 사이트맵에 포함하고 싶다면 이 옵션을 사용할 수 있습니다.

```js title="astro.config.mjs" ins={8}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      customPages: ['https://stargazers.club/external-page', 'https://stargazers.club/external-page2'],
    }),
  ],
});
```

### entryLimit

사이트맵 파일당 최대 항목 수입니다. 기본값은 45000입니다. 항목이 더 있으면 사이트맵 색인과 여러 사이트맵이 생성됩니다. [대규모 사이트맵 분할에 대한 설명](https://developers.google.com/search/docs/advanced/sitemaps/large-sitemaps)을 참조하세요.

```js title="astro.config.mjs" ins={8}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      entryLimit: 10000,
    }),
  ],
});
```

### changefreq, lastmod, priority

이러한 옵션은 [Sitemap XML 사양](https://www.sitemaps.org/protocol.html)의 `<changefreq>`, `<lastmod>`, `<priority>` 태그에 해당합니다.

`changefreq` 및 `priority`는 Google에서 무시됩니다.

:::note
Astro의 [통합 API](/ko/reference/integrations-reference/) 제한으로 인해 이 통합에서는 특정 페이지의 소스 코드를 분석할 수 없습니다. 이 구성 옵션은 *사이트 전체* 기준으로 `changefreq`, `lastmod`, `priority`를 설정할 수 있습니다. 페이지별로 이러한 값을 설정하는 방법은 다음 옵션 **serialize**를 참조하세요.
:::

```js title="astro.config.mjs" ins={8-10}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      changefreq: 'weekly',
      priority: 0.7,
      lastmod: new Date('2022-02-24'),
    }),
  ],
});
```

### serialize

디스크에 쓰기 직전에 각 사이트맵 항목에 대해 호출되는 함수입니다. 이 함수는 비동기식일 수 있습니다.

다음 속성을 가질 수 있는 `SitemapItem` 객체를 매개변수로 받습니다.

* `url` (페이지 URL의 절대경로). 이는 `SitemapItem`에 포함되도록 보장되는 유일한 속성입니다.
* `changefreq`
* `lastmod` (ISO 형식의 날짜, `String` 타입)
* `priority`
* `links`.

이 `links` 속성에는 상위 페이지를 포함한 대체 페이지의 `LinkItem` 목록이 포함되어 있습니다.

`LinkItem` 타입에는 `url` (지정된 언어에 대한 이 페이지 버전의 정규화된 URL)과 `lang` (이 페이지 버전을 대상으로 지원되는 언어 코드)의 두 가지 필드가 있습니다.

`serialize` 함수는 터치 여부에 관계없이 `SitemapItem`을 반환해야 합니다.

아래 예시는 사이트맵 특정 속성을 개별적으로 추가하는 기능을 보여줍니다.

```js title="astro.config.mjs" ins={8-18}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      serialize(item) {
        if (/exclude-from-sitemap/.test(item.url)) {
          return undefined;
        }
        if (/your-special-page/.test(item.url)) {
          item.changefreq = 'daily';
          item.lastmod = new Date();
          item.priority = 0.9;
        }
        return item;
      },
    }),
  ],
});
```

### i18n

사이트맵을 현지화하려면 이 `i18n` 옵션에 객체를 전달하세요.

이 객체에는 두 가지 필수 속성이 있습니다.

* `defaultLocale`: `String`. 해당 값은 `locales` 키 중 하나로 존재해야 합니다.
* `locales`: `Record<String, String>`, 키/값 - 쌍. 키는 페이지 경로에서 로케일 부분을 찾는 데 사용됩니다. 값은 언어 속성이며, 영어 알파벳과 하이픈만 허용됩니다.

[언어 속성에 대해 자세히 알아보기](https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/lang).

[현지화에 대해 자세히 알아보기](https://developers.google.com/search/docs/advanced/crawling/localized-versions#all-method-guidelines).

```js title="astro.config.mjs" ins={8-15}
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://stargazers.club',
  integrations: [
    sitemap({
      i18n: {
        defaultLocale: 'en', // `https://stargazers.club/` 뒤에 `es` 또는 `fr`이 포함되지 않은 모든 URL은 기본 로케일, 즉 `en`으로 처리됩니다.
        locales: {
          en: 'en-US', // `defaultLocale` 값은 `locales` 키에 있어야 합니다.
          es: 'es-ES',
          fr: 'fr-CA',
        },
      },
    }),
  ],
});
```

결과 사이트맵은 다음과 같습니다.

```xml title="sitemap-0.xml"
...
  <url>
    <loc>https://stargazers.club/</loc>
    <xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/"/>
    <xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/"/>
    <xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/"/>
  </url>
  <url>
    <loc>https://stargazers.club/es/</loc>
    <xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/"/>
    <xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/"/>
    <xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/"/>
  </url>
  <url>
    <loc>https://stargazers.club/fr/</loc>
    <xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/"/>
    <xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/"/>
    <xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/"/>
  </url>
  <url>
    <loc>https://stargazers.club/es/second-page/</loc>
    <xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/second-page/"/>
    <xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/second-page/"/>
    <xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/second-page/"/>
  </url>
...
```

## 예시

* 공식 Astro 웹사이트는 Astro Sitemap을 사용하여 [사이트맵](https://astro.build/sitemap-index.xml)을 생성합니다.
* [GitHub에서 Astro Sitemap을 사용하는 프로젝트 찾아보기](https://github.com/search?q=%22%40astrojs%2Fsitemap%22+path%3Apackage.json\&type=Code)에서 더 많은 예시를 확인하세요!

[astro-integration]: /ko/guides/integrations-guide/
